﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;

namespace Reap.Core.Caching {

	/// <summary>
	/// Repersents a StaticCache
	/// Yuhao 2014.6.27
	/// </summary>
	public  partial class PerRequestCacheManager:ICacheManager {

		#region Fields
		private readonly HttpContextBase _context;
		#endregion

		#region .ctor
		public PerRequestCacheManager(HttpContextBase context)
		{
			this._context = context;
		}
		#endregion


		/// <summary>
		/// Creates a new instance of the RequestCache class
		/// </summary>
		/// <returns></returns>
		protected virtual IDictionary GetItems()
		{
			if (_context != null)
			{
				return _context.Items;
			}
			return null;
		}
		/// <summary>
		/// Gets or sets the value associated with the specified key.
		/// </summary>
		/// <typeparam name="T">Type</typeparam>
		/// <param name="key">The key of the value to get.</param>
		/// <returns>The value associated with the specified key.</returns>
		public T Get<T>(string key)
		{
			var items = GetItems();
			if (items == null)
				return default(T);
			return (T) items[key];
		}
		/// <summary>
		/// Adds the specified key and object to the cache.
		/// </summary>
		/// <param name="key">key</param>
		/// <param name="data">Data</param>
		/// <param name="cacheTime">Cache time</param>
		public void Set(string key, object data, int cacheTime)
		{
			var items = GetItems();
			if(items==null)
				return;
			if (data != null)
			{
				if (items.Contains(key))
					items[key] = data;
				else
				{
					items.Add(key,data);
				}
			}
		}

		/// <summary>
		/// Gets a value indicating whether the value associated with the specified key is cached
		/// </summary>
		/// <param name="key">key</param>
		/// <returns>Result</returns>
		public bool IsSet(string key)
		{
			var items = GetItems();
			if (items == null)
				return false;
			return (items[key] == null);
		}

		/// <summary>
		/// Removes the value with the specified key from the cache
		/// </summary>
		/// <param name="key">/key</param>
		public void Remove(string key)
		{
			var items = GetItems();
			if(items==null)
				return;
			items.Remove(key);
		}
		/// <summary>
		/// Removes items by pattern
		/// </summary>
		/// <param name="pattern">pattern</param>
		public void RemoveByPattern(string pattern)
		{
			var items = GetItems();
			if(items==null)
				return;
			var enumerator = items.GetEnumerator();
			var regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline);
			var keysToRomove = new List<string>();
			while (enumerator.MoveNext())
			{
				if(regex.IsMatch(enumerator.Key.ToString()))
					keysToRomove.Add(enumerator.Key.ToString());
			}
			foreach (var key in keysToRomove)
			{
				items.Remove(key);
			}
		}
		/// <summary>
		/// Clear all cache data
		/// </summary>
		public void Clear()
		{
			var items = GetItems();
			if(items==null)
				return;
			var enumerator = items.GetEnumerator();
			var keysToRemove = new List<string>();
			while (enumerator.MoveNext())
			{
				keysToRemove.Add(enumerator.Key.ToString());
			}
			foreach (var key in keysToRemove)
			{
				items.Remove(key);
			}
		}


	}
}
